package com.itheima.log.aop;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itheima.log.domain.Log;
import com.itheima.log.service.LogService;
import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;

/**
 * 切面处理类，操作日志记录
 */
@Component
@Aspect
public class LogAspect {

    @Resource
    LogService logService;
    //注意写法
//    @annotation：用于匹配当前执行方法持有指定注解的方法
    @Pointcut(value ="@annotation(com.itheima.log.aop.LogRec)")
    public void pd(){

    }

    /**
     * 每次操作后保存到记录表中
     *
     * @param joinPoint 切入点
     */
    @AfterReturning("pd()")
    public void AfterReturning(JoinPoint joinPoint) throws JsonProcessingException {
        logSave(joinPoint,null);
    }
    @AfterThrowing(value = "pd()",throwing = "throwable")
    public void saveOperLog(JoinPoint joinPoint, Throwable throwable) throws Exception {
        logSave(joinPoint, throwable);
    }




    public void logSave(JoinPoint joinPoint,Throwable throwable) throws JsonProcessingException {
        //创建对象
        Log log = new Log();
        Object[] args = joinPoint.getArgs();
        if (args !=null && args.length > 0){
            //转成json格式存放
            log.setParam(new ObjectMapper().writeValueAsString(args));
        }

        //获取织入点处的方法名
        String name = joinPoint.getSignature().getName();
        log.setMethod(name);

        //获取目标类的class文件然后反射获取所有方法
        for (Method method : joinPoint.getTarget().getClass().getMethods()) {
            if (name.equals(method.getName())){
                //获取方法上的注解
                LogRec annotation = method.getAnnotation(LogRec.class);
                //获取注解的type
                String name1 = annotation.type().name();
                log.setType(name1);
                //获取注解的desc
                String desc = annotation.desc();
                log.setDesc(desc);
                break;
            }
        }

        if (throwable != null){
            log.setError(throwable.getMessage());
        }


        logService.save(log);
    }

}